home *** CD-ROM | disk | FTP | other *** search
/ SGI Developer Toolbox 6.1 / SGI Developer Toolbox 6.1 - Disc 4.iso / src / swtools / libdwarf / pro_frame.c < prev    next >
Encoding:
C/C++ Source or Header  |  1994-08-02  |  9.1 KB  |  334 lines

  1. /*
  2.     pro_frame.c
  3.     $Revision: 1.15 $    $Date: 1993/10/06 00:01:25 $    
  4.     $Source: /cmplrs.src/v4.00/libdwarf/RCS/pro_frame.c,v $
  5.  
  6.     Frame information routines
  7. */
  8.  
  9. #include <stdio.h>
  10. #include <string.h>
  11. #include <limits.h>
  12. #include "pro_incl.h"
  13. #include "pro_frame.h"
  14.  
  15. static void _dwarf_pro_add_to_fde(Dwarf_P_Fde fde, Dwarf_P_Frame_Pgm inst);
  16.  
  17. /*-------------------------------------------------------------------------
  18.     This functions adds a cie struct to the debug pointer. Its in the
  19.     form of a linked list.
  20.     augmenter: string reps augmentation (implementation defined)
  21.     code_align: alignment of code
  22.     data_align: alignment of data
  23.     init_bytes: byts having initial instructions
  24.     init_n_bytes: number of bytes of initial instructions
  25. --------------------------------------------------------------------------*/
  26. Dwarf_Unsigned
  27. dwarf_add_frame_cie(
  28.     Dwarf_P_Debug dbg,
  29.     char *augmenter,
  30.     Dwarf_Small code_align,
  31.     Dwarf_Small data_align,
  32.     Dwarf_Small return_reg,
  33.     Dwarf_Ptr init_bytes,
  34.     Dwarf_Unsigned init_n_bytes,
  35.     Dwarf_Error *error)
  36. {
  37.     Dwarf_P_Cie curcie;
  38.  
  39.     if (dbg->de_frame_cies == NULL) {
  40.         dbg->de_frame_cies = (Dwarf_P_Cie) 
  41.         _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Cie_s));
  42.         if (dbg->de_frame_cies == NULL) {
  43.         DWARF_P_DBG_ERROR(dbg,DW_DLE_CIE_ALLOC,DW_DLV_NOCOUNT);
  44.         }
  45.         curcie = dbg->de_frame_cies;
  46.         dbg->de_n_cie = 1;
  47.          dbg->de_last_cie = curcie;
  48.     } 
  49.     else {
  50.         curcie = dbg->de_last_cie;
  51.         curcie->cie_next = (Dwarf_P_Cie) 
  52.         _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Cie_s));
  53.         if (curcie->cie_next == NULL) {
  54.         DWARF_P_DBG_ERROR(dbg,DW_DLE_CIE_ALLOC,DW_DLV_NOCOUNT);
  55.         }
  56.         curcie = curcie->cie_next;
  57.         dbg->de_n_cie++;
  58.         dbg->de_last_cie = curcie;    
  59.     }
  60.     curcie->cie_version = DW_CIE_VERSION;
  61.     curcie->cie_aug = augmenter;
  62.     curcie->cie_code_align = code_align;
  63.     curcie->cie_data_align = data_align;
  64.     curcie->cie_ret_reg = return_reg;
  65.     curcie->cie_inst = (char *) init_bytes;
  66.     curcie->cie_inst_bytes = init_n_bytes;
  67.     curcie->cie_next = NULL;
  68.     return dbg->de_n_cie;
  69. }
  70.  
  71.  
  72. /*-------------------------------------------------------------------------
  73.     This functions adds a fde struct to the debug pointer. Its in the
  74.     form of a linked list.
  75.     die: subprogram/function die corresponding to this fde
  76.     cie: cie referred to by this fde, obtained from call to 
  77.         add_frame_cie() routine.
  78.     virt_addr: beginning address
  79.     code_len: length of code reps by the fde
  80. --------------------------------------------------------------------------*/
  81. Dwarf_Unsigned
  82. dwarf_add_frame_fde(
  83.     Dwarf_P_Debug dbg,
  84.     Dwarf_P_Fde fde,
  85.     Dwarf_P_Die die,
  86.     Dwarf_Unsigned cie,
  87.     Dwarf_Unsigned virt_addr,
  88.     Dwarf_Unsigned code_len,
  89.     Dwarf_Unsigned  symidx,
  90.     Dwarf_Error *error)
  91. {
  92.     Dwarf_P_Fde curfde;
  93.     
  94.     fde->fde_die = die;
  95.     fde->fde_cie = cie;
  96.     fde->fde_initloc = virt_addr;
  97.     fde->fde_r_symidx = symidx;
  98.     fde->fde_addr_range = code_len;
  99.     
  100.     curfde = dbg->de_last_fde;
  101.     if (curfde == NULL) {
  102.         dbg->de_frame_fdes = fde;
  103.         dbg->de_last_fde = fde;
  104.         dbg->de_n_fde = 1;
  105.     }
  106.     else {
  107.         curfde->fde_next = fde;
  108.         dbg->de_last_fde = fde;
  109.         dbg->de_n_fde++;
  110.     }
  111.     return dbg->de_n_fde;
  112. }
  113.  
  114. /*-------------------------------------------------------------------
  115.     Create a new fde 
  116. ---------------------------------------------------------------------*/
  117. Dwarf_P_Fde 
  118. dwarf_new_fde (Dwarf_P_Debug dbg, Dwarf_Error *error)
  119. {
  120.     Dwarf_P_Fde fde;
  121.  
  122.     fde = (Dwarf_P_Fde)
  123.         _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Fde_s));
  124.     if (fde == NULL) {
  125.         DWARF_P_DBG_ERROR(dbg,DW_DLE_FDE_ALLOC,(Dwarf_P_Fde) DW_DLV_BADADDR);
  126.     }
  127.     fde->fde_next = NULL;
  128.     fde->fde_inst = NULL;
  129.     fde->fde_n_inst = 0;
  130.     fde->fde_n_bytes = 0;
  131.     fde->fde_last_inst = NULL;
  132.     return fde;
  133. }
  134.  
  135. /*------------------------------------------------------------------------
  136.     Add cfe_offset instruction to fde
  137. -------------------------------------------------------------------------*/
  138. Dwarf_P_Fde
  139. dwarf_fde_cfa_offset(
  140.     Dwarf_P_Fde fde, 
  141.     Dwarf_Unsigned reg,
  142.     Dwarf_Signed offset,
  143.     Dwarf_Error *error)
  144. {
  145.     Dwarf_Ubyte opc, regno;
  146.     char *ptr;
  147.     Dwarf_P_Frame_Pgm curinst;
  148.     int nbytes;
  149.  
  150.     curinst = (Dwarf_P_Frame_Pgm)
  151.        _dwarf_p_get_alloc(NULL,sizeof(struct Dwarf_P_Frame_Pgm_s));
  152.     if (curinst == NULL) {
  153.         DWARF_P_DBG_ERROR(NULL,DW_DLE_FPGM_ALLOC,(Dwarf_P_Fde) DW_DLV_BADADDR);
  154.     }
  155.     opc = DW_CFA_offset;
  156.     regno = reg;
  157.     if (regno & 0xc0) {
  158.         DWARF_P_DBG_ERROR(NULL,DW_DLE_REGNO_OVFL,(Dwarf_P_Fde) DW_DLV_BADADDR);
  159.     }
  160.     opc = opc | regno;    /* lower 6 bits are register number */
  161.     curinst->dfp_opcode = opc;
  162.     ptr = _dwarf_pro_encode_leb128(offset, &nbytes);
  163.     curinst->dfp_args = ptr;
  164.     curinst->dfp_nbytes = nbytes;
  165.     curinst->dfp_next = NULL;
  166.  
  167.     _dwarf_pro_add_to_fde(fde,curinst);
  168.     return fde;
  169. }
  170.  
  171. /*
  172.     Generic routine to add opcode to fde instructions. val1 and
  173.     val2 are parameters whose interpretation depends on the 'op'.
  174. */
  175. Dwarf_P_Fde
  176. dwarf_add_fde_inst(
  177.     Dwarf_P_Fde     fde,
  178.     Dwarf_Small     op,
  179.     Dwarf_Unsigned     val1,
  180.     Dwarf_Unsigned     val2,
  181.     Dwarf_Error     *error
  182. )
  183. {
  184.     Dwarf_P_Frame_Pgm     curinst;
  185.     int         nbytes, nbytes1, nbytes2;
  186.     Dwarf_Ubyte     db;
  187.     Dwarf_Half         dh;
  188.     Dwarf_Word         dw;
  189.     Dwarf_Unsigned     du;
  190.     char         *ptr, *ptr1, *ptr2;
  191.  
  192.     /* debug trace. uncomment if needed. 
  193.     printf ("add_fde: op = %d, val1 = 0x%llx, val2 = 0x%llx \n", 
  194.             op, val1, val2);
  195.     */
  196.  
  197.     nbytes = 0;
  198.     ptr = NULL;
  199.     curinst = (Dwarf_P_Frame_Pgm)
  200.     _dwarf_p_get_alloc(NULL,sizeof(struct Dwarf_P_Frame_Pgm_s));
  201.     if (curinst == NULL) {
  202.     _dwarf_p_error(NULL, error, DW_DLE_FPGM_ALLOC);
  203.     return((Dwarf_P_Fde)DW_DLV_BADADDR);
  204.     }
  205.  
  206.     switch (op) {
  207.  
  208.         case DW_CFA_advance_loc:
  209.         if (val1 <= 0x3f) {
  210.             db = val1;
  211.             op |= db;
  212.         } 
  213.         else if (val1 <= UCHAR_MAX) {
  214.             op = DW_CFA_advance_loc1;
  215.             db = val1;
  216.             ptr = (char *) _dwarf_p_get_alloc(NULL, 1);
  217.             if (ptr == NULL) {
  218.                 _dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC);
  219.             return((Dwarf_P_Fde)DW_DLV_BADADDR);
  220.             }
  221.             memcpy((void *)ptr, (const void *)&db,1);
  222.             nbytes = 1;
  223.         }
  224.         else if (val1 <= USHRT_MAX) {
  225.             op = DW_CFA_advance_loc2;
  226.             dh = val1;
  227.             ptr = (char *) _dwarf_p_get_alloc(NULL, 2);
  228.         if (ptr == NULL) {
  229.                 _dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC);
  230.             return((Dwarf_P_Fde)DW_DLV_BADADDR);
  231.             }
  232.             memcpy((void *)ptr, (const void *)&dh,2);
  233.             nbytes = 2;
  234.         }
  235.         else if (val1 <= ULONG_MAX) {
  236.             op = DW_CFA_advance_loc4;
  237.             dw = val1;
  238.             ptr = (char *) _dwarf_p_get_alloc(NULL, 4);
  239.             if (ptr == NULL) {
  240.                 _dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC);
  241.             return((Dwarf_P_Fde)DW_DLV_BADADDR);
  242.             }
  243.             memcpy((void *)ptr, (const void *)&dw,4);
  244.             nbytes = 4;
  245.         }
  246.         else {
  247.             op = DW_CFA_MIPS_advance_loc8;
  248.             du = val1;
  249.             ptr = (char *)_dwarf_p_get_alloc(NULL, sizeof(Dwarf_Unsigned));
  250.             if (ptr == NULL) {
  251.                 _dwarf_p_error(NULL, error, DW_DLE_STRING_ALLOC);
  252.             return((Dwarf_P_Fde)DW_DLV_BADADDR);
  253.             }
  254.             memcpy((void *)ptr, (const void *)&du,8);
  255.             nbytes = 8;
  256.         }
  257.             break;
  258.  
  259.         case DW_CFA_offset:
  260.         if (val1 <= MAX_6_BIT_VALUE) {
  261.             db = val1;
  262.             op |= db;
  263.             ptr = _dwarf_pro_encode_leb128(val2, &nbytes);
  264.         }
  265.         else {
  266.         op = DW_CFA_offset_extended;
  267.  
  268.             ptr1 =  _dwarf_pro_encode_leb128(val1, &nbytes1);
  269.             ptr2 =  _dwarf_pro_encode_leb128(val2, &nbytes2);
  270.             ptr =  (char *) _dwarf_p_get_alloc(NULL, nbytes1+nbytes2);
  271.             memcpy(ptr, ptr1, nbytes1);
  272.             memcpy(ptr+nbytes1, ptr2, nbytes2);
  273.             _dwarf_p_dealloc(NULL, ptr1);
  274.             _dwarf_p_dealloc(NULL, ptr2);
  275.             nbytes = nbytes1 + nbytes2;
  276.         }
  277.         break;
  278.  
  279.     case DW_CFA_undefined:
  280.     case DW_CFA_same_value:
  281.         ptr = _dwarf_pro_encode_leb128(val1, &nbytes);
  282.         break;
  283.  
  284.     case DW_CFA_register:
  285.         case DW_CFA_def_cfa:
  286.         ptr1 =  _dwarf_pro_encode_leb128(val1, &nbytes1);
  287.         ptr2 =  _dwarf_pro_encode_leb128(val2, &nbytes2);
  288.         ptr =  (char *) _dwarf_p_get_alloc(NULL, nbytes1+nbytes2);
  289.         memcpy(ptr, ptr1, nbytes1);
  290.         memcpy(ptr+nbytes1, ptr2, nbytes2);
  291.         _dwarf_p_dealloc(NULL, ptr1);
  292.         _dwarf_p_dealloc(NULL, ptr2);
  293.         nbytes = nbytes1 + nbytes2;
  294.         break;
  295.         
  296.     case DW_CFA_def_cfa_register:
  297.     case DW_CFA_def_cfa_offset:
  298.         ptr =  _dwarf_pro_encode_leb128(val1, &nbytes);
  299.         break;
  300.  
  301.         default:
  302.         break;
  303.     }
  304.  
  305.     curinst->dfp_opcode = op;
  306.     curinst->dfp_args = ptr;
  307.     curinst->dfp_nbytes = nbytes;
  308.     curinst->dfp_next = NULL;
  309.  
  310.     _dwarf_pro_add_to_fde(fde, curinst);
  311.     return fde;
  312. }
  313.  
  314.  
  315. /*------------------------------------------------------------------------
  316.     instructions are added to fde in the form of a linked
  317.     list. This functions manages the linked list
  318. -------------------------------------------------------------------------*/
  319. void 
  320. _dwarf_pro_add_to_fde(Dwarf_P_Fde fde, Dwarf_P_Frame_Pgm curinst)
  321. {
  322.     if (fde->fde_last_inst) {
  323.         fde->fde_last_inst->dfp_next = curinst;
  324.         fde->fde_last_inst = curinst;
  325.         fde->fde_n_inst++;
  326.         fde->fde_n_bytes += curinst->dfp_nbytes + sizeof(Dwarf_Ubyte) ;
  327.     } 
  328.     else {
  329.         fde->fde_last_inst = fde->fde_inst = curinst;
  330.         fde->fde_n_inst = 1;
  331.         fde->fde_n_bytes = curinst->dfp_nbytes + sizeof(Dwarf_Ubyte);
  332.     }
  333. }
  334.